package com.xydtech.ecard.ecard.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xydtech.common.core.domain.entity.SysDept;
import com.xydtech.common.enums.ApiContant;
import com.xydtech.common.enums.ResultStatus;
import com.xydtech.common.exception.ApiException;
import com.xydtech.common.model.ResponseModel;
import com.xydtech.common.token.JwtTokenUtil;
import com.xydtech.common.utils.DateUtils;
import com.xydtech.common.utils.JasyptUtils;
import com.xydtech.common.utils.ServletUtils;
import com.xydtech.common.utils.StringUtils;
import com.xydtech.common.utils.sql.SqlUtil;
import com.xydtech.system.domain.SysWechatApplet;
import com.xydtech.system.service.ISysDeptService;
import com.xydtech.system.service.ISysWechatAppletService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * web层通用数据处理
 *
 * @author JHON
 */
public class EcardApiBaseController {
    protected final Logger logger = LoggerFactory.getLogger(EcardApiBaseController.class);

    /**
     * 获取request
     */
    public HttpServletRequest getRequest() {
        return ServletUtils.getRequest();
    }

    /**
     * 获取response
     */
    public HttpServletResponse getResponse() {
        return ServletUtils.getResponse();
    }

    /**
     * 页面跳转
     */
    public String redirect(String url) {
        return StringUtils.format("redirect:{}", url);
    }

    @Autowired
    private ISysWechatAppletService wechatAppletService;
    @Autowired
    private ISysDeptService sysDeptService;

    @Value("${jasypt.salt}")
    private String salt;

    /**
     * 获取数据加密盐值
     * @return
     */
    public String getSalt(){
        String decrypt = JasyptUtils.decrypt("hcyz", salt);
        return decrypt;
    }

    /**
     * 获取当前登录人的信息
     *
     * @param
     * @return com.xydtech.scrmredpack.busi.custinfo.domain.ScrmCustInfo
     * @throws
     * @Title getCustInfo
     * @author Daniel
     * @Date 2020/6/3 13:08
     **/
    public String getCurrentUserId() throws ApiException {
        HttpServletRequest request = getRequest();
        String authorization = request.getHeader("authorization");

        String currentUserId = null;
        try {
            currentUserId = JwtTokenUtil.getUserIdFromToken(authorization);
        } catch (Exception e) {
            throw new ApiException(ResultStatus.TOKEN_INVALID);
        }
        return currentUserId;
    }

    /**
     * 获取appId
     * 这个方法不再使用，改为根据登录人的县级机构去数据库查appid
     * @return
     * @throws ApiException
     */
    public String getAppId() throws ApiException {
        HttpServletRequest request = getRequest();
        String appId = request.getHeader("appid");
        return appId;
    }

    /**
     * 根据机构id获取当前小程序信息
     *
     * @return
     * @throws ApiException
     */
    public SysWechatApplet getAppIdByDeptId(Long deptId) throws ApiException {
        //根据机构id获取当前小程序信息
        SysDept sysDept = sysDeptService.selectSecondLevelDeptByDeptId(deptId);
        return wechatAppletService.getWechatAppletByDeptId(ApiContant.APPLETTYPE_ECARD, sysDept.getDeptId());
    }

    /**
     * 设置请求分页数据
     */
    protected void startPage() {
        HttpServletRequest request = getRequest();

        String pageNumStr = request.getParameter("pageNum");
        String pageSizeStr = request.getParameter("pageSize");
        String orderByStr = request.getParameter("orderBy");
        if (StringUtils.isNotNull(pageNumStr) && StringUtils.isNotNull(pageSizeStr)) {
            int pageNum = Integer.parseInt(pageNumStr);
            int pageSize = Integer.parseInt(pageSizeStr);

            String orderBy = SqlUtil.escapeOrderBySql(orderByStr);
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    /**
     * 响应请求分页数据
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    protected ResponseModel getTableResponse(List<?> list) {
        return new ResponseModel(ResultStatus.SUCCESS, new PageInfo(list).getTotal(), list);
    }

    /**
     * 添加水印
     *
     * @param imageFile 图片
     * @param imgUrl    保存路径
     * @param position  水印字符串
     * @return
     */
    public void addWaterMask(MultipartFile imageFile, String imgUrl, String position,
                             String coordinate, String userName, String deptName) throws Exception{
        InputStream in = null;
        try {
            in = imageFile.getInputStream();
            BufferedImage image = ImageIO.read(in);
            //图片高度
            int imgHeight = image.getHeight();
            //图片宽度
            int imgWidth = image.getWidth();

            logger.info("图片宽高" + imgWidth + "," + imgHeight);

            //获取 Graphics2D 对象
            Graphics2D g = image.createGraphics();
            //设置绘图区域
            g.drawImage(image, imgWidth, imgHeight, null);
            //设置字体
            int timeFontSize = 30;
            Font font = new Font("Microsoft YaHei", Font.PLAIN, timeFontSize);
            g.setFont(font);
            // 根据图片的背景设置水印颜色
            g.setColor(Color.white);

            //获取水印文字行数
            int posLength = position.length();
            int lineLength = (int) (imgWidth / 35.5);//根据图片宽度算出每行文字长度
            int line = (int) Math.ceil(posLength /(imgWidth / 35.5));//算出行数

            //获取时间文字长度
            int timLen = g.getFontMetrics(g.getFont()).charsWidth(DateUtils.getTime().toCharArray(), 0, DateUtils.getTime().length());
            int timeX = (imgWidth - timLen) / 20;
            int timeY = imgHeight * (88- ((line-1) * 3 )) / 100;

            //获取水印文字总长度
            int fontlen = g.getFontMetrics(g.getFont()).charsWidth(position.toCharArray(), 0, posLength);
            int dateAddrX = (imgWidth - fontlen) / 9;
            int dateAddrY = imgHeight * (91- ((line-1) * 3 )) / 100;
            g.drawString(DateUtils.getTime(), timeX+120, timeY);
            //水印文字过长换行处理
            if (posLength > 25){
                int j = 91- ((line-1) * 3 );
                for (int i = 0; i < line; i++) {
                    if (i == line - 1){
                        g.drawString(position.substring(lineLength * i, posLength), timeX+120, imgHeight * j / 100);
                    } else {
                        g.drawString(position.substring(lineLength * i, lineLength * (i + 1)), timeX+120, imgHeight * j / 100);
                    }
                    j = j + 3;
                }
            } else {
                g.drawString(position, timeX+120, dateAddrY);
            }

            //经纬度处理
            int coordinateY = imgHeight * 94 / 100;
            g.drawString(coordinate, timeX+120, coordinateY);
            //客户经理+机构名称处理
            int userNameY = imgHeight * 97 / 100;
            g.drawString(userName + "  " + deptName, timeX+150, userNameY);

            Graphics2D g2 = image.createGraphics();
            //设置绘图区域
            g2.drawImage(image, imgWidth, imgHeight, null);
            //设置字体
            Font font2 = new Font("Microsoft YaHei", Font.BOLD, timeFontSize);
            g2.setFont(font2);
            // 根据图片的背景设置水印颜色
            g2.setColor(Color.white);
            //时间加粗处理（空格不要删）
            g2.drawString("时   间：", timeX, timeY);
            //地址加粗处理（空格不要删）
            g2.drawString("地   址：", timeX, dateAddrY);
            //经纬度加粗处理
            g2.drawString("经纬度：", timeX, coordinateY);
            //客户经理+机构名称加粗处理
            g2.drawString("客户经理：", timeX, userNameY);

            //设置透明
            AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f);
            g.setComposite(alphaComposite);
            //设置抗锯齿
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setComposite(alphaComposite);
            //设置抗锯齿
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.dispose();
            g2.dispose();
            ImageIO.write(image, "jpg", new File(imgUrl));
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("图片添加水印失败！"+e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /**
     * 影像资料添加水印（没有地址和经纬度字段）
     *
     * @param imageFile 图片
     * @param imgUrl    保存路径
     * @param position  水印字符串
     * @return
     */
    public void addBusiflWaterMask(MultipartFile imageFile, String imgUrl, String position, String userName, String deptName) throws Exception{
        InputStream in = null;
        try {
            in = imageFile.getInputStream();
            BufferedImage image = ImageIO.read(in);
            //图片高度
            int imgHeight = image.getHeight();
            //图片宽度
            int imgWidth = image.getWidth();

            logger.info("图片宽高" + imgWidth + "," + imgHeight);

            //获取 Graphics2D 对象
            Graphics2D g = image.createGraphics();
            //设置绘图区域
            g.drawImage(image, imgWidth, imgHeight, null);
            //设置字体
            int timeFontSize = 30;
            Font font = new Font("Microsoft YaHei", Font.PLAIN, timeFontSize);
            g.setFont(font);
            // 根据图片的背景设置水印颜色
            g.setColor(Color.white);

            //获取水印文字行数
            int posLength = position.length();
            int lineLength = (int) (imgWidth / 35.5);//根据图片宽度算出每行文字长度
            int line = (int) Math.ceil(posLength /(imgWidth / 35.5));//算出行数

            //获取时间文字长度
            int timLen = g.getFontMetrics(g.getFont()).charsWidth(DateUtils.getTime().toCharArray(), 0, DateUtils.getTime().length());
            int timeX = (imgWidth - timLen) / 20;
            int timeY = imgHeight * (88- ((line-1) * 3 )) / 100;

            //获取水印文字总长度
            int fontlen = g.getFontMetrics(g.getFont()).charsWidth(position.toCharArray(), 0, posLength);
            int dateAddrX = (imgWidth - fontlen) / 9;
            int dateAddrY = imgHeight * (91- ((line-1) * 3 )) / 100;
            g.drawString(DateUtils.getTime(), timeX+120, timeY);
            //水印文字过长换行处理
            if (posLength > 25){
                int j = 91- ((line-1) * 3 );
                for (int i = 0; i < line; i++) {
                    if (i == line - 1){
                        g.drawString(position.substring(lineLength * i, posLength), timeX+120, imgHeight * j / 100);
                    } else {
                        g.drawString(position.substring(lineLength * i, lineLength * (i + 1)), timeX+120, imgHeight * j / 100);
                    }
                    j = j + 3;
                }
            } else {
                g.drawString(position, timeX+120, dateAddrY);
            }
            //客户经理+机构名称处理
            int userNameY = imgHeight * 94 / 100;
            g.drawString(userName + "  " + deptName, timeX+120, userNameY);

            Graphics2D g2 = image.createGraphics();
            //设置绘图区域
            g2.drawImage(image, imgWidth, imgHeight, null);
            //设置字体
            Font font2 = new Font("Microsoft YaHei", Font.BOLD, timeFontSize);
            g2.setFont(font2);
            // 根据图片的背景设置水印颜色
            g2.setColor(Color.white);
            //时间加粗处理（空格不要删）
            g2.drawString("时   间：", timeX, timeY);
            //地址加粗处理（空格不要删）
            g2.drawString("类   型：", timeX, dateAddrY);
            //客户经理+机构名称加粗处理
            g2.drawString("客户经理：", timeX, userNameY);

            //设置透明
            AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f);
            g.setComposite(alphaComposite);
            //设置抗锯齿
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setComposite(alphaComposite);
            //设置抗锯齿
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.dispose();
            g2.dispose();
            ImageIO.write(image, "jpg", new File(imgUrl));
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("图片添加水印失败！"+e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
